package org.xgame.comm.util;

import com.alibaba.fastjson.annotation.JSONField;
import com.alibaba.fastjson.serializer.JSONSerializer;
import com.alibaba.fastjson.serializer.PropertyPreFilter;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;

/**
 * JSONField 注解过滤
 */
public class JSONFieldPropertyPreFilter implements PropertyPreFilter {
    /**
     * 目标类
     */
    private final Class<?> _targetClazz;

    /**
     * 包含列表
     */
    private final Set<String> _includeSet = new HashSet<>();

    /**
     * 类参数构造器
     *
     * @param targetClazz 目标类
     */
    public JSONFieldPropertyPreFilter(Class<?> targetClazz) {
        if (null == targetClazz) {
            throw new IllegalArgumentException("targetClazz is null");
        }

        _targetClazz = targetClazz;

        // 获取所有字段
        Field[] fieldArray = targetClazz.getDeclaredFields();

        for (Field field : fieldArray) {
            JSONField jsonField = field.getAnnotation(JSONField.class);

            if (null != jsonField &&
                jsonField.serialize()) {
                _includeSet.add(jsonField.name());
            }
        }

        // 获取所有方法
        Method[] methodArray = targetClazz.getDeclaredMethods();

        for (Method method : methodArray) {
            JSONField jsonField = method.getAnnotation(JSONField.class);

            if (null != jsonField &&
                jsonField.serialize()) {
                _includeSet.add(jsonField.name());
            }
        }
    }

    @Override
    public boolean apply(JSONSerializer serializer, Object source, String name) {
        return _targetClazz.isInstance(source) &&
            _includeSet.contains(name);
    }
}
